package com.fjwt.gz.service.other.export;

import cn.hutool.core.date.DateUtil;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.db.dto.StatMemberNumDTO;
import com.fjwt.gz.db.entity.AgentAppEntity;
import com.fjwt.gz.db.entity.SysExportTaskEntity;
import com.fjwt.gz.db.vo.AgentInfoVO;
import com.fjwt.gz.db.vo.StatMemberNumVO;
import com.fjwt.gz.service.activity.AbstractExportReport;
import com.fjwt.gz.service.impl.AgentAppService;
import com.fjwt.gz.service.impl.AgentInfoService;
import com.fjwt.gz.service.impl.StatMemberNumService;
import com.fjwt.gz.service.mapper.StatMemberNumMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * ------ 机构会员通报表导出报表
 */
@Slf4j
@Service
public class StatMemberNumExportReport extends AbstractExportReport<StatMemberNumVO> {

    @Autowired
    private AgentAppService agentAppService;
    @Autowired
    private StatMemberNumService statMemberNumService;
    @Autowired
    private StatMemberNumMapper statMemberNumMapper;
    @Autowired
    private AgentInfoService agentInfoService;

    public static final String AGENT_DETAILS = "agentDetails";
    public static final String DEVELOPMENT_SITUATION = "developmentSituation";

    private static final Map<String, String> agentDetailsHeaderAliasMap = new HashMap<>();
    static {
        agentDetailsHeaderAliasMap.put("agentNo", "网点编码");
        agentDetailsHeaderAliasMap.put("agentName", "网点名称");
        agentDetailsHeaderAliasMap.put("pId", "网点归属区县编码");
        agentDetailsHeaderAliasMap.put("pName", "区县机构");
        agentDetailsHeaderAliasMap.put("totalOldMemberNum", "存量权益会员");
        agentDetailsHeaderAliasMap.put("totalSyncMemberNum", "已迁移权益会员");
        agentDetailsHeaderAliasMap.put("lastWeekSyncMemberNum", "周迁移权益会员");
        agentDetailsHeaderAliasMap.put("monthSyncMemberNum", "月迁移权益会员");
        agentDetailsHeaderAliasMap.put("yearSyncMemberNum", "年迁移权益会员");
        agentDetailsHeaderAliasMap.put("totalMemberNum", "存量会员人数");
        agentDetailsHeaderAliasMap.put("lastWeekMemberNum", "周新增存量会员");
        agentDetailsHeaderAliasMap.put("monthMemberNum", "月新增存量会员");
        agentDetailsHeaderAliasMap.put("yearMemberNum", "年新增存量会员");
        agentDetailsHeaderAliasMap.put("totalCstmMemberNum", "实名会员人数");
        agentDetailsHeaderAliasMap.put("lastWeekCstmMemberNum", "周新增实名会员");
        agentDetailsHeaderAliasMap.put("monthCstmMemberNum", "月新增实名会员");
        agentDetailsHeaderAliasMap.put("yearCstmMemberNum", "年新增实名会员");
    }

    private static final Map<String, String> developmentSituationHeaderAliasMap = new HashMap<>();
    static {
        developmentSituationHeaderAliasMap.put("agentName", "单位");
        developmentSituationHeaderAliasMap.put("nextAgentNum", "网点数");
        developmentSituationHeaderAliasMap.put("totalOldMemberNum", "郑州邮政权益中心会员");
        developmentSituationHeaderAliasMap.put("totalMemberNum", "存量会员数");
        developmentSituationHeaderAliasMap.put("totalMemberNumAvg", "存量点均");
        developmentSituationHeaderAliasMap.put("lastWeekMemberNum", "周新增存量会员");
        developmentSituationHeaderAliasMap.put("lastWeekMemberNumAvg", "周新增存量会员点均");
        developmentSituationHeaderAliasMap.put("monthMemberNum", "月新增存量会员");
        developmentSituationHeaderAliasMap.put("monthMemberNumAvg", "月新增存量会员点均");
        developmentSituationHeaderAliasMap.put("yearMemberNum", "年新增存量会员");
        developmentSituationHeaderAliasMap.put("yearMemberNumAvg", "年新增存量会员点均");
        developmentSituationHeaderAliasMap.put("newMemberNum", "新发展会员");
        developmentSituationHeaderAliasMap.put("totalSyncMemberNum", "迁移会员");
        developmentSituationHeaderAliasMap.put("lastWeekSyncMemberNum", "周新增迁移会员");
        developmentSituationHeaderAliasMap.put("monthSyncMemberNum", "月新增迁移会员");
        developmentSituationHeaderAliasMap.put("yearSyncMemberNum", "年新增迁移会员");
        developmentSituationHeaderAliasMap.put("totalSyncMemberRatio", "会员迁移率");
        developmentSituationHeaderAliasMap.put("totalCstmMemberNum", "实名会员");
        developmentSituationHeaderAliasMap.put("lastWeekCstmMemberNum", "周新增实名会员");
        developmentSituationHeaderAliasMap.put("lastWeekCstmMemberSort", "周新增实名会员排名");
        developmentSituationHeaderAliasMap.put("monthCstmMemberNum", "月新增实名会员");
        developmentSituationHeaderAliasMap.put("monthCstmMemberSort", "月新增实名会员排名");
        developmentSituationHeaderAliasMap.put("yearCstmMemberNum", "年新增实名会员");
        developmentSituationHeaderAliasMap.put("yearCstmMemberSort", "年新增实名会员排名");
    }


    @Override
    public String exportActivityExcel(SysExportTaskEntity sysExportTaskEntity) {
        StatMemberNumDTO statMemberNumDTO = getRequestParam(sysExportTaskEntity.getRequestParam(), StatMemberNumDTO.class);
        if (AGENT_DETAILS.equals(statMemberNumDTO.getExportType())) {
            if (ObjectUtils.isEmpty(statMemberNumDTO.getStatDate())) {
                statMemberNumDTO.setStatDate(DateUtil.beginOfDay(DateUtil.offsetDay(DateUtil.date(), -1)));
            }
            if (ObjectUtils.isNotEmpty(statMemberNumDTO.getAgentNo())) {
                statMemberNumDTO.setAgentNo(null);
                List<String> agentNos = agentInfoService.queryAllSubAgentNo(statMemberNumDTO.getAgentNo());
                agentNos.add(null);
                statMemberNumDTO.setAgentNoList(agentNos);
            }
            List<StatMemberNumVO> list = statMemberNumMapper.getAgentDetails(statMemberNumDTO);

            for (StatMemberNumVO record : list) {
                statMemberNumService.setAgentName(record);
            }
            return createExcelAndUploadOssUrl(list, agentDetailsHeaderAliasMap, sysExportTaskEntity);
        }else if (DEVELOPMENT_SITUATION.equals(statMemberNumDTO.getExportType())) {
            if (ObjectUtils.isEmpty(statMemberNumDTO.getStatDate())) {
                statMemberNumDTO.setStatDate(DateUtil.beginOfDay(DateUtil.offsetDay(DateUtil.date(), -1)));
            }

            if (ObjectUtils.isNotEmpty(statMemberNumDTO.getAgentNo())) {
                AgentInfoVO agentInfos = agentInfoService.getAgentInfos(statMemberNumDTO.getAgentNo());
                List<String> agentNos = new ArrayList<>();
                if (ObjectUtils.isNotEmpty(agentInfos.getChildren())) {
                    agentNos = agentInfos.getChildren().stream().map(AgentInfoVO::getAgentNo).collect(Collectors.toList());
                }
                agentNos.add(statMemberNumDTO.getAgentNo());
                agentNos.add(null);
                statMemberNumDTO.setAgentNoList(agentNos);
                statMemberNumDTO.setTotalAgentNo(statMemberNumDTO.getAgentNo());
                statMemberNumDTO.setAgentNo(null);
            }else {
                AgentAppEntity agentApp = agentAppService.getOne(AgentAppEntity.gw().eq(AgentAppEntity::getAppId, statMemberNumDTO.getLiteAppId()));
                if (ObjectUtils.isEmpty(agentApp)) {
                    throw new BizException("未查询到小程序归属机构");
                }
                statMemberNumDTO.setTotalAgentNo(agentApp.getAgentNo());
                statMemberNumDTO.setLevel(agentInfoService.getAgentInfo(statMemberNumDTO.getTotalAgentNo()).getLevel() + 1);
            }
            List<StatMemberNumVO> statMemberNumVOList = statMemberNumMapper.getAgentDetails(statMemberNumDTO);

            for (StatMemberNumVO record : statMemberNumVOList) {
                statMemberNumService.setAgentName(record);
                Integer nextAgentNum = statMemberNumService.getDefaultValue(record.getNextAgentNum());
                record.setTotalMemberNumAvg(record.getTotalMemberNum() / nextAgentNum);
                record.setLastWeekMemberNumAvg(record.getLastWeekMemberNum() / nextAgentNum);
                record.setMonthMemberNumAvg(record.getMonthMemberNum() / nextAgentNum);
                record.setYearMemberNumAvg(record.getYearMemberNum() / nextAgentNum);
                record.setNewMemberNum(record.getTotalMemberNum() - record.getTotalSyncMemberNum());
                record.setTotalSyncMemberRatio(new BigDecimal(record.getTotalSyncMemberNum()).divide(new BigDecimal(statMemberNumService.getDefaultValue(record.getTotalMemberNum())), 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2));
                record.setTotalCstmMemberRatio(new BigDecimal(record.getTotalCstmMemberNum()).divide(new BigDecimal(statMemberNumService.getDefaultValue(record.getTotalMemberNum())), 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2));
            }

            StatMemberNumVO statMemberNumVO = statMemberNumVOList.stream().filter(item -> statMemberNumDTO.getTotalAgentNo().equals(item.getAgentNo())).findFirst().orElse(null);
            if (ObjectUtils.isNotEmpty(statMemberNumVO)) {
                statMemberNumVOList.remove(statMemberNumVO);

                StringBuilder titles = new StringBuilder("郑邮享会员发展情况通报：截止");
                titles.append(DateUtil.format(statMemberNumDTO.getStatDate(), "MM月dd日"));
                if (ObjectUtils.isNotEmpty(statMemberNumVO)) {
                    titles.append("，郑邮享会员");
                    titles.append(new BigDecimal(statMemberNumVO.getTotalMemberNum()).divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));
                    titles.append("（存量会员数）万户，实名会员全市共");
                    titles.append(new BigDecimal(statMemberNumVO.getTotalCstmMemberNum()).divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));
                    titles.append("（实名会员数）万户，认证率为");
                    titles.append(statMemberNumVO.getTotalCstmMemberRatio());
                    titles.append("%。");
                }
                titles.append("\n【郑邮享会员情况】");
                String weekAddTop = statMemberNumVOList.stream().filter(item -> ObjectUtils.isNotEmpty(item.getAgentNo())).sorted(Comparator.comparing(StatMemberNumVO::getLastWeekMemberNumAvg).reversed()).limit(3).map(StatMemberNumVO::getAgentName).collect(Collectors.joining("、"));
                String weekAddLast = statMemberNumVOList.stream().filter(item -> ObjectUtils.isNotEmpty(item.getAgentNo())).sorted(Comparator.comparing(StatMemberNumVO::getLastWeekMemberNumAvg)).limit(3).map(StatMemberNumVO::getAgentName).collect(Collectors.joining("、"));
                String yearAddTop = statMemberNumVOList.stream().filter(item -> ObjectUtils.isNotEmpty(item.getAgentNo())).sorted(Comparator.comparing(StatMemberNumVO::getYearMemberNumAvg).reversed()).limit(3).map(StatMemberNumVO::getAgentName).collect(Collectors.joining("、"));
                String yearAddLast = statMemberNumVOList.stream().filter(item -> ObjectUtils.isNotEmpty(item.getAgentNo())).sorted(Comparator.comparing(StatMemberNumVO::getYearMemberNumAvg)).limit(3).map(StatMemberNumVO::getAgentName).collect(Collectors.joining("、"));
                titles.append("\n点均周新增前三：").append(weekAddTop);
                titles.append("\n点均周新增后三：").append(weekAddLast);
                titles.append("\n点均年新增前三：").append(yearAddTop);
                titles.append("\n点均年新增后三：").append(yearAddLast);

                titles.append("\n【实名认证率情况】");
                String cstmTop = statMemberNumVOList.stream().filter(item -> ObjectUtils.isNotEmpty(item.getAgentNo())).sorted(Comparator.comparing(StatMemberNumVO::getTotalCstmMemberRatio).reversed()).limit(3).map(StatMemberNumVO::getAgentName).collect(Collectors.joining("、"));
                String cstmLast = statMemberNumVOList.stream().filter(item -> ObjectUtils.isNotEmpty(item.getAgentNo())).sorted(Comparator.comparing(StatMemberNumVO::getTotalCstmMemberRatio)).limit(3).map(StatMemberNumVO::getAgentName).collect(Collectors.joining("、"));
                titles.append("\n点均周新增前三：").append(cstmTop);
                titles.append("\n点均周新增后三：").append(cstmLast);

                statMemberNumVO.setAgentName("总计");
                statMemberNumVOList.add(statMemberNumVO);
            }
            return createExcelAndUploadOssUrl(statMemberNumVOList, developmentSituationHeaderAliasMap, sysExportTaskEntity);
        }

        return "";
    }
}
